package com.zlm.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * 自定义前后端分离的filter
 */


public class LoginFilter extends UsernamePasswordAuthenticationFilter {

    /**
     * 重写他默认获取表单的数据
     *
     * @param request
     * @param response
     * @return
     * @throws AuthenticationException
     */
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

        // 1.判断是否是post
        if (!request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }

        // 2.判断是否是JSON格式的
        if (request.getContentType().equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)) {
            // 3.从json格式中获取用户名和密码

            // 下面就是自定义了
            try {
                Map<String, String> userInfo = new ObjectMapper().readValue(request.getInputStream(), Map.class);

                // 这里就是通过我们前面securityConfig里面指定的userNameParameter来实现的
                String username = userInfo.get(getUsernameParameter());
                String password = userInfo.get(getPasswordParameter());

                System.out.println("用户名：" + username + ":密码：" + password);

                // 根据源码要自己生成一个UsernamePasswordAuthenticationToken去验证账号密码
                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
                setDetails(request, authenticationToken);
                return this.getAuthenticationManager().authenticate(authenticationToken);

            } catch (IOException e) {
                e.printStackTrace();
            }


        }


        // 如果都不是就走父类的 就是表单认证
        return super.attemptAuthentication(request, response);

    }
}
